﻿using System;
using System.Collections.Generic;

namespace ZOIL.DataModel
{
    /// <summary>
    /// Attribute that is used to specify that a class is a viewmodel for the given type
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
    public class ViewModelFor : Attribute
    {
        /// <summary>
        /// the dictionary that holds all the types and their corresponding types of viewmodels
        /// </summary>
        private static readonly Dictionary<Type, Type> ViewModelsFor = new Dictionary<Type, Type>();

        /// <summary>
        /// the type for which the class is a viewmodel for
        /// </summary>
        public Type T;

        public ViewModelFor(Type t)
        {
            T = t;
        }

        /// <summary>
        /// initializes the viewmodels
        /// get all types from the plugin manager, that contain the ViewFor attribute
        /// note: you have to initialize the pluginmanager to register types for the attribute
        /// </summary>
        /// <param name="t"></param>
        public static void InitViewModelsFor(Type t)
        {
            var viewModelForTypes = PluginManager.Instance.GetAttributedTypes(typeof(ViewModelFor));

            foreach (var viewModelForType in viewModelForTypes)
            {
                var atts = GetCustomAttributes(viewModelForType);

                foreach (var a in atts)
                {
                    if (a is ViewModelFor)
                    {
                        var vmf = a as ViewModelFor;
                        if (vmf.T == t)
                        {
                            ViewModelsFor[t] = viewModelForType;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// returns the viewmodel for the given type
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public static BaseViewModel GetViewModelFor(Type t)
        {
            if (!ViewModelsFor.ContainsKey(t))
            {
                InitViewModelsFor(t);
            }

            if (ViewModelsFor.ContainsKey(t))
            {
                var viewModelType = ViewModelsFor[t];
                var bvm = (BaseViewModel) Activator.CreateInstance(viewModelType);
                return bvm;
            }
            return new BaseViewModel();
        }
    }
}